#include "RWLock.h"

RWLock :: RWLock() {
	sem_init(&sem_room, 0, 1);
	sem_init(&sem_turn, 0, 1);
	
	countReaders = 0;
	sem_init(&sem_LSwitchMutex, 0, 1);

}

void RWLock :: rlock() {
	sem_wait(&sem_turn);
	sem_post(&sem_turn);
	LSwitchLock(&sem_room);
}
void RWLock :: wlock() {
	sem_wait(&sem_turn);
	sem_wait(&sem_room);

}
void RWLock :: runlock() {
	LSwitchUnlock(&sem_room);

}
void RWLock :: wunlock() {
	sem_post(&sem_turn);
	sem_post(&sem_room);

}

void RWLock::LSwitchLock(sem_t *s){
	sem_wait(&sem_LSwitchMutex);
	countReaders++;
	if(countReaders == 1)	sem_wait(s);
	sem_post(&sem_LSwitchMutex);
}

void RWLock::LSwitchUnlock(sem_t *s){
	sem_wait(&sem_LSwitchMutex);
	countReaders--;
	if(countReaders == 0)	sem_post(s);
	sem_post(&sem_LSwitchMutex);	
}

RWLock::~RWLock(){
	
	sem_close(&sem_room);
	sem_close(&sem_LSwitchMutex);
	sem_close(&sem_turn);

}
